package com.maxd.service.area;

import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.maxd.bean.area.AreaInfoTree;
import com.maxd.model.AreaInfo;
import com.maxd.respository.area.AreaInfoRepository;
import com.maxd.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AreaService implements IAreaService {

    @Autowired
    private AreaInfoRepository areaInfoRepository;

    @Autowired
    private LoadingCache<String, List<AreaInfoTree>> areaCache;


    public List<AreaInfoTree> queryAllByCache() {
        try {
            return areaCache.get("ALL");
        } catch (Exception e) {
            log.error("queryAllByCache error.", e);
            return queryAll();
        }
    }

    @Override
    public List<AreaInfo> provenceList() {
        List<AreaInfoTree> areaInfoTrees = queryAllByCache();
        return areaInfoTrees.stream().map(this::convert).collect(Collectors.toList());

    }

    @Override
    public AreaInfoTree provenceInfo(String areaCode) {
        List<AreaInfoTree> areaInfoTrees = queryAllByCache();
        for (AreaInfoTree areaInfoTree : areaInfoTrees) {
            if(areaInfoTree.getAreaCode().equals(areaCode)) {
                return areaInfoTree;
            }
        }
        return null;
    }

    @Override
    public List<AreaInfoTree> queryAll() {
        log.info("加载所有的地址编码");
        List<AreaInfo> areaInfoList = areaInfoRepository.findAll();
        // 所有的区域列表
        List<AreaInfoTree> areaTreeList = areaInfoList.stream()
                .map(this::convert)
                .sorted((Comparator<AreaInfo>) (o1, o2) -> {
                    if (o1.getAreaCode().length() - o2.getAreaCode().length() != 0) {
                        return o1.getAreaCode().length() - o2.getAreaCode().length();
                    }
                    return o1.getAreaCode().compareTo(o2.getAreaCode());
                })
                .collect(Collectors.toList());
        log.info("查询到区域编码的总数量为:{}", areaTreeList.size());
        // key为编码，value为区域信息
        Map<String, AreaInfoTree> areaTreeMap = areaTreeList.stream()
                .collect(Collectors.toMap(e -> e.getAreaCode(), e -> e, (e1, e2) -> e1));
        List<AreaInfoTree> topList = Lists.newArrayList();
        for (AreaInfoTree areaInfoTree : areaTreeList) {
            if(StringUtils.isEmpty(areaInfoTree.getParentCode())) {
                topList.add(areaInfoTree);
            } else {
                AreaInfoTree parent = areaTreeMap.get(areaInfoTree.getParentCode());
                if(parent != null) {
                    List<AreaInfoTree> subList = parent.getSubList();
                    if(subList == null) {
                        subList = Lists.newArrayList();
                        parent.setSubList(subList);
                    }
                    subList.add(areaInfoTree);
                } else {
                    log.info("区域的父编码不存在: {}", JsonUtils.toJsonString(parent));
                }
            }
        }
        return topList;
    }

    private AreaInfoTree convert(AreaInfo areaInfo) {
        AreaInfoTree areaInfoTree = new AreaInfoTree();
        BeanUtils.copyProperties(areaInfo, areaInfoTree);
        return areaInfoTree;
    }

    private AreaInfo convert(AreaInfoTree areaInfoTree) {
        AreaInfo areaInfo = new AreaInfo();
        BeanUtils.copyProperties(areaInfoTree, areaInfo);
        return areaInfo;
    }
}
